package org.apache.lucene.ocean.database;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.lucene.ocean.TransactionSystem;
import org.apache.lucene.ocean.name.NameService;
import org.apache.lucene.ocean.name.NameService.Node;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Resolves differences between nodes. The task is run at a timed interval.
 * Every time the task is executed it loads the nodes for the cell from the name
 * service.
 * 
 * Probably the easiest way to efficiently rectify is to choose ranges of ids to obtain from the 
 * other node, md5 them and then compare with the transactions on the node.  Either that or simply obtain
 * the actual transaction ids and compare them.  Most likely either way would work fine, the latter may be 
 * advantageous in that it is simpler to implement for now.
 * 
 */
public class Rectifier {
  final static Logger LOG = LoggerFactory.getLogger(Rectifier.class);
  String nodeId;
  String cellId;
  long interval;
  ScheduledExecutorService executor;
  NameService nameService;
  TransactionSystem transactionSystem;

  public Rectifier(String nodeId, String cellId, long interval, TransactionSystem transactionSystem) {
    this.nodeId = nodeId;
    this.cellId = cellId;
    this.interval = interval;
    this.transactionSystem = transactionSystem;
    executor = (ScheduledExecutorService) Executors.newSingleThreadScheduledExecutor();
    executor.scheduleWithFixedDelay(new RecitifyTask(), interval, interval, TimeUnit.MILLISECONDS);
  }

  public class RecitifyTask implements Runnable {
    public void run() {
      try {
        Node[] nodes = nameService.getNodesByCell(cellId);
        for (Node node : nodes) {
          // if not this node
          if (!node.id.equals(nodeId)) {
            rectifyForNode(node);
          }
        }
      } catch (Exception ex) {
        LOG.error("", ex);
      }
    }
  }
  
  /**
   * Finds latest transaction ids from the node and checks to see if the local node has
   * all of them.
   * @param node
   */
  public void rectifyForNode(Node node) {
    
  }
}
